
#include <stdio.h>
#include "mbed.h"
#include "GUI.h"
#include "GUIDRV_Lin.h"
#include "EwGui.h"

/*********************************************************************
 *
 *       Defines
 *
 **********************************************************************
 */


/*********************************************************************
 *
 *       Static data
 *
 **********************************************************************
 */

static EwGui* ewGui = 0;
static Timer ewGuiTimer;
static uint32_t ewGuiMsTime = 0;

/*********************************************************************
 *
 *       Public code
 *
 **********************************************************************
 */

void ew_registerGuiHandle(EwGui* gui) {
    ewGui = gui;
}

/*********************************************************************
 *
 *       GUI_X_Config
 *
 * Purpose:
 *   Called during the initialization process in order to set up the
 *   available memory for the GUI.
 */
void GUI_X_Config(void) {

    if (!ewGui) return;

    //
    // Assign memory to emWin
    //

    GUI_ALLOC_AssignMemory(ewGui->getMemoryBlockAddress(),
            ewGui->getMemoryBlockSize());
    //	GUI_ALLOC_SetAvBlockSize(0x80);
}

/*********************************************************************
 *
 *       LCD_X_Config
 *
 * Purpose:
 *   Called during the initialization process in order to set up the
 *   display driver configuration.
 */
void LCD_X_Config(void) {

    if (!ewGui) return;

    GUI_DEVICE_CreateAndLink(&GUIDRV_Lin_16_API, GUICC_M565, 0, 0);

    //
    // Display driver configuration, required for Lin-driver
    //
    LCD_SetPosEx(0, 0, 0);
    if (LCD_GetSwapXYEx(0)) {
        LCD_SetSizeEx  (0, ewGui->getDisplayHeight(), ewGui->getDisplayWidth());
        LCD_SetVSizeEx (0, ewGui->getDisplayHeight(), ewGui->getDisplayWidth());
    } else {
        LCD_SetSizeEx  (0, ewGui->getDisplayWidth(), ewGui->getDisplayHeight());
        LCD_SetVSizeEx (0, ewGui->getDisplayWidth(), ewGui->getDisplayHeight());
    }
    LCD_SetVRAMAddrEx(0, (void*)0);
}

/*********************************************************************
 *
 *       LCD_X_DisplayDriver
 *
 * Purpose:
 *   This function is called by the display driver for several purposes.
 *   To support the according task the routine needs to be adapted to
 *   the display controller. Please note that the commands marked with
 *   'optional' are not cogently required and should only be adapted if
 *   the display controller supports these features.
 *
 * Parameter:
 *   LayerIndex - Index of layer to be configured
 *   Cmd        - Please refer to the details in the switch statement below
 *   pData      - Pointer to a LCD_X_DATA structure
 *
 * Return Value:
 *   < -1 - Error
 *     -1 - Command not handled
 *      0 - Ok
 */
int LCD_X_DisplayDriver(unsigned LayerIndex, unsigned Cmd, void * pData) {
    //	LCD_X_SETORG_INFO * pSetOrg;
    int r;
    U32 TouchOrientation;

    if (!ewGui) return -1;

    switch (Cmd) {
    //
    // Required
    //
    case LCD_X_INITCONTROLLER:
        //
        // Called during the initialization process in order to set up the
        // display controller and put it into operation. If the display
        // controller is not initialized by any external routine this needs
        // to be adapted by the customer...
        //
        // ...

        //
        // Set display size and video-RAM address
        //
        //		LCD_SetSizeEx (800, 480, 0);
        //		LCD_SetVSizeEx(800, 480, 0);
        LCD_SetVRAMAddrEx(0, (void*)ewGui->getFrameBufferAddress());

        TouchOrientation = (GUI_MIRROR_X * LCD_GetMirrorXEx(0)) |
                (GUI_MIRROR_Y * LCD_GetMirrorYEx(0)) |
                (GUI_SWAP_XY  * LCD_GetSwapXYEx (0)) ;
        GUI_TOUCH_SetOrientation(TouchOrientation);

        return 0;
    case LCD_X_SETORG:
        //
        // Required for setting the display origin which is passed in the 'xPos' and 'yPos' element of p
        //

        // pSetOrg = (LCD_X_SETORG_INFO *)pData;
        //        LPC_LCD->UPBASE = VRAM_ADDR_PHYS +
        //                (pSetOrg->yPos * YSIZE_PHYS * /*PIXEL_WIDTH*/ 2);  // Needs to be set, before LCDC is enabled

        return 0;
    default:
        r = -1;

    }

    return r;
}



/*********************************************************************
 *
 *      Timing:
 *                 GUI_X_GetTime()
 *                 GUI_X_Delay(int)

  Some timing dependent routines require a GetTime
  and delay function. Default time unit (tick), normally is
1 ms.
 */

int GUI_X_GetTime(void) {
    ewGuiMsTime += ewGuiTimer.read_ms();
    ewGuiTimer.reset();
    return ewGuiMsTime;
}

void GUI_X_Delay(int ms) {
    wait_ms(ms);
}

/*********************************************************************
 *
 *       GUI_X_Init()
 *
 * Note:
 *     GUI_X_Init() is called from GUI_Init is a possibility to init
 *     some hardware which needs to be up and running before the GUI.
 *     If not required, leave this routine blank.
 */
void GUI_X_Init(void) {
    ewGuiTimer.start();
}


/*********************************************************************
 *
 *       GUI_X_ExecIdle
 *
 * Note:
 *  Called if WM is in idle state
 */

void GUI_X_ExecIdle(void) {}

/*********************************************************************
 *
 *      Multitasking:
 *
 *                 GUI_X_InitOS()
 *                 GUI_X_GetTaskId()
 *                 GUI_X_Lock()
 *                 GUI_X_Unlock()
 *
 * Note:
 *   The following routines are required only if emWin is used in a
 *   true multi task environment, which means you have more than one
 *   thread using the emWin API.
 *   In this case the
 *                       #define GUI_OS 1
 *  needs to be in GUIConf.h
 */


//static OS_RSEMA RSema;

void GUI_X_InitOS(void)    { /*OS_CreateRSema(&RSema);*/    }
void GUI_X_Unlock(void)    { /*OS_Unuse(&RSema);*/ }
void GUI_X_Lock(void)      { /*OS_Use(&RSema);*/  }
U32  GUI_X_GetTaskId(void) { return 0; /*(U32)OS_GetTaskID();*/ }

/*********************************************************************
 *
 *      Logging: OS dependent

Note:
  Logging is used in higher debug levels only. The typical target
  build does not use logging and does therefor not require any of
  the logging routines below. For a release build without logging
  the routines below may be eliminated to save some space.
  (If the linker is not function aware and eliminates unreferenced
  functions automatically)

 */

void GUI_X_Log     (const char *s) { GUI_USE_PARA(s); }
void GUI_X_Warn    (const char *s) { GUI_USE_PARA(s); }
void GUI_X_ErrorOut(const char *s) { GUI_USE_PARA(s); }


/*********************************************************************
 *
 *       GUI_TOUCH_X_ActivateX()
 *
 * Function decription:
 *   Called from GUI, if touch support is enabled.
 *   Switches on voltage on X-axis,
 *   prepares measurement for Y-axis.
 *   Voltage on Y-axis is switched off.
 */
void GUI_TOUCH_X_ActivateX(void) {
}

/*********************************************************************
 *
 *       GUI_TOUCH_X_ActivateY()
 *
 * Function decription:
 *   Called from GUI, if touch support is enabled.
 *   Switches on voltage on Y-axis,
 *   prepares measurement for X-axis.
 *   Voltage on X-axis is switched off.
 */
void GUI_TOUCH_X_ActivateY(void) {
}

/*********************************************************************
 *
 *       GUI_TOUCH_X_MeasureX()
 *
 * Function decription:
 *   Called from GUI, if touch support is enabled.
 *   Measures voltage of X-axis.
 */
int  GUI_TOUCH_X_MeasureX(void) {
    if (!ewGui) return 0;

    return ewGui->getTouchX();
}

/*********************************************************************
 *
 *       GUI_TOUCH_X_MeasureY()
 *
 * Function decription:
 *   Called from GUI, if touch support is enabled.
 *   Measures voltage of Y-axis.
 */
int  GUI_TOUCH_X_MeasureY(void) {
    if (!ewGui) return 0;

    return ewGui->getTouchY();
}

/*************************** End of file ****************************/



